<?php
/**
 * CN-FBA发货单上传（国内仓发fba仓）
 */
namespace App\Admin\Controllers\Delivery;

use App\Models\Basics\FbaWarehouse;
use App\Models\Basics\SysCountry;
use App\Models\Basics\SysICountry;
use App\Models\Delivery\FBADelivery;
use App\Models\Inventory\InventoryCn;
use App\Models\Product\ProductAmazonSku;
use App\Models\Product\ProductSku;
use App\Models\Sys\Logs;
use App\Util\RExcel;
use Encore\Admin\Controllers\AdminController;
use Encore\Admin\Facades\Admin;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Symfony\Component\HttpFoundation\File\UploadedFile;
class FBAUploadController extends AdminController{

    protected $title = 'CN至FBA-发货单上传';

    protected function grid()
    {
        return view('delivery.fba-upload.index');
    }

    public function upload(Request $request){
        $countryId = $request->get('country_id');
        $areaId = SysICountry::getAreaIdByCountryId($countryId);
        if(!$areaId){
            admin_toastr('发货国家无对应发货站点！','error');
            return back()->withInput();
        }
        $accountId = $request->get('account_id');
        $file = $request->file('source_file');
        if ($file->isValid()) {
            $re = $this->_importFile($file,$accountId,$areaId,$countryId);
            if(is_array($re)) {
                if($re['flag']){
                    admin_toastr('文件：'.$re['data'].' 上传成功！');
                }else{
                    admin_toastr($re['data'],'error');
                }
            }else{
                return $re;
            }
        }else{
            admin_toastr('无效文件！','error');
        }
        return back()->withInput();
    }

    private function _importFile(UploadedFile $file,$accountId,$areaId,$countryId){
        try{
            DB::beginTransaction();
            $lines = file($file);
            $data = [];
            $pData = [];
            $length = count($lines);
            for ($i = 0; $i < $length; $i++) {
                $line = str_replace(["\r\n","\n"], '', $lines[$i]);
                if (empty($line)) {
                    break;
                }
                $data[] = str_getcsv($line, "\t");
            }
            for ($j = $i + 2; $j < $length; $j++) {
                $pData[] = str_getcsv($lines[$j], "\t");
            }
            $deliveryNo = $data[0][1];
            $dAddress = $data[3][1];
            $totalSku = $data[4][1];
            $totalUnit = $data[5][1];
            $delivery = FBADelivery::query()->where('delivery_no',$deliveryNo)->first();
            if (!empty($delivery)) {
                DB::rollBack();
                return ['flag' => false, 'data' => '发货单已存在，请勿重复上传！'];
            }
            if(strlen($dAddress) < 10){
                $countryTemp = SysCountry::getCountryById($countryId);
                if(in_array($countryTemp,['US','CA'])){
                    $dAddressTemp = FbaWarehouse::getAddressIdByAddressCode($dAddress);
                    if(!$dAddressTemp){
                        DB::rollBack();
                        return ['flag' => false, 'data' => '系统未匹配到该仓库编码，请先添加！'];
                    }
                }
            }
            $errors = [];
            $items = [];
            $unitPrice = [];
            foreach ($pData as $pd) {
                if (count($pd) < 10) {
                    $errors[$pd[0]] = '数据缺失';
                    continue;
                }
                $sellerSku = trim($pd[0]);
                $asin = trim($pd[2]);
                $fnSku = trim($pd[3]);
                $applyNum = (isset($pd[11])) ? intval($pd[11]) : intval($pd[9]);
                $amazonProduct = ProductAmazonSku::query()->where('seller_sku', $sellerSku)->where('country_id',$countryId)->first();
                if (empty($amazonProduct)) {
                    $errors[$sellerSku] = '系统不存在该国家下的亚马逊SKU';
                    continue;
                }
                if(!$amazonProduct->fnsku){
                    $errors[$sellerSku] = '该亚马逊SKU的FNSKU为空';
                    continue;
                }
                if($fnSku != 'X002LF0K9T' && $fnSku != $amazonProduct->fnsku){
                    $errors[$sellerSku] = '该亚马逊SKU的FNSKU('.$amazonProduct->fnsku.')与文件中FNSKU('.$fnSku.')不匹配';
                    continue;
                }
                if(!array_key_exists($amazonProduct->psku_id,$unitPrice)){
                    $ps = ProductSku::getModelById($amazonProduct->psku_id);
                    $unitPrice[$amazonProduct->psku_id] = ProductSku::getPuPrice($ps);
                }
                $items[] = [
                    'psku_id'           => $amazonProduct->psku_id,
                    'apply_num'         => $applyNum,
                    'seller_sku'        => $sellerSku,
                    'asin'              => $asin,
                    'fnsku'             => $fnSku,
                    'unit_price'        => $unitPrice[$amazonProduct->psku_id]
                ];
            }
            if(empty($items)){
                $errors[] = '无符合条件的产品';
            }
            if(empty($errors)){
                $inventoryErrors = [];
                foreach ($items as $item){
                    $inventory = InventoryCn::query()
                        ->where('area_id',$areaId)
                        ->where('psku_id',$item['psku_id'])
                        ->lockForUpdate()
                        ->first();
                    if (!$inventory) {
                        $inventoryErrors[$item['seller_sku']] = '无库存';
                        continue;
                    }
                    if ($inventory->instant < $item['apply_num']) {
                        $inventoryErrors[$item['seller_sku']] = '库存不足，差额：'.($item['apply_num'] - $inventory->instant);
                        continue;
                    }
                    $inventory->instant -= $item['apply_num'];
                    $inventory->reserve += $item['apply_num'];
                    $flag = $inventory->save();
                    if(!$flag){
                        $inventoryErrors[$item['seller_sku']] = '库存更新失败';
                        continue;
                    }
                }
                if(!empty($inventoryErrors)){
                    DB::rollBack();
                    return RExcel::importResult($inventoryErrors);
                }else{
                    if(strlen($dAddress) < 10){
                        $dAddressCode = $dAddress;
                        $country = SysCountry::getCountryById($countryId);
                        if(in_array($country,['US','CA'])){
                            $_dAddress = FbaWarehouse::getAddressIdByAddressCode($dAddress);
                            if($_dAddress){
                                $dAddress = $_dAddress;
                            }
                        }
                    }else{
                        $dAddressCode = '';
                    }
                    //添加CN-FBA发货单
                    $delivery = FBADelivery::query()->create([
                        'delivery_no' => $deliveryNo,
                        'account_id' => $accountId,
                        'area_id' => $areaId,
                        'country_id' => $countryId,
                        'seller_id' => Admin::user()->id ?? 0,
                        'd_address_code' => $dAddressCode,
                        'd_address' => $dAddress,
                        'total_sku' => $totalSku,
                        'total_unit' => $totalUnit,
                    ]);
                    $delivery->detail()->createMany($items);
                    if($delivery){
                        Logs::logs('fba-delivery',"创建发货单：{$deliveryNo}",$delivery->id);
                        DB::commit();
                        return ['flag' => true,'data' => $file->getClientOriginalName()];
                    }else{
                        DB::rollBack();
                        return ['flag' => false,'data' => '创建发货单失败！'];
                    }
                }
            }else{
                DB::rollBack();
                return RExcel::importResult($errors);
            }
        }catch(\Exception $e){
            DB::rollBack();
            report($e);
            return ['flag' => false,'data' => '系统异常！'];
        }
    }
}
